package com.ruoyi.base.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.ruoyi.base.domain.MBasestaff;
import com.ruoyi.base.domain.MPerformance;
import com.ruoyi.base.mapper.MBasestaffMapper;
import com.ruoyi.base.vo.IdAndYear;
import com.ruoyi.base.vo.IncomeTaxVo;
import net.sf.jsqlparser.expression.LongValue;
import org.apache.poi.hpsf.Decimal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.base.mapper.MSalarydetailsMapper;
import com.ruoyi.base.domain.MSalarydetails;
import com.ruoyi.base.service.IMSalarydetailsService;

/**
 * 薪资明细Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-08-11
 */
@Service
public class MSalarydetailsServiceImpl implements IMSalarydetailsService 
{
    @Autowired
    private MSalarydetailsMapper mSalarydetailsMapper;

    @Autowired
    private MBasestaffMapper mBasestaffMapper;

    /**
     * 查询薪资明细
     * 
     * @param id 薪资明细主键
     * @return 薪资明细
     */
    @Override
    public MSalarydetails selectMSalarydetailsById(Long id)
    {
        return mSalarydetailsMapper.selectMSalarydetailsById(id);
    }

    /**
     * 查询薪资明细列表
     * 
     * @param mSalarydetails 薪资明细
     * @return 薪资明细
     */
    @Override
    public List<MSalarydetails> selectMSalarydetailsList(MSalarydetails mSalarydetails)
    {
        return mSalarydetailsMapper.selectMSalarydetailsList(mSalarydetails);
    }

    /**
     * 新增薪资明细
     * 
     * @param mSalarydetails 薪资明细
     * @return 结果
     */
    @Override
    public int insertMSalarydetails(MSalarydetails mSalarydetails)
    {
        return mSalarydetailsMapper.insertMSalarydetails(mSalarydetails);
    }

    /**
     * 修改薪资明细
     * 
     * @param mSalarydetails 薪资明细
     * @return 结果
     */
    @Override
    public int updateMSalarydetails(MSalarydetails mSalarydetails)
    {
        return mSalarydetailsMapper.updateMSalarydetails(mSalarydetails);
    }

    /**
     * 批量删除薪资明细
     * 
     * @param ids 需要删除的薪资明细主键
     * @return 结果
     */
    @Override
    public int deleteMSalarydetailsByIds(Long[] ids)
    {
        return mSalarydetailsMapper.deleteMSalarydetailsByIds(ids);
    }

    /**
     * 删除薪资明细信息
     * 
     * @param id 薪资明细主键
     * @return 结果
     */
    @Override
    public int deleteMSalarydetailsById(Long id)
    {
        return mSalarydetailsMapper.deleteMSalarydetailsById(id);
    }

    private String yearmonth = new SimpleDateFormat("yyyy-MM").format(new Date());

    @Override
    public String addMSalarydetails() {

        IdAndYear idAndYear = new IdAndYear();
        Date date = new Date();
        //获取当前月份

        //获取当前月份
      idAndYear.setS_yearmonth(new SimpleDateFormat("yyyy-MM").format(date));

        //查询所有员工，并生成当月薪资明细
        List<MBasestaff> mBasestaffList=mBasestaffMapper.selectMBasestaffList(null);
        for (MBasestaff mBasestaff : mBasestaffList) {
            idAndYear.setS_id(mBasestaff.getsId());
            //若果当月不存在该用户的数据，则生成
            if ( mSalarydetailsMapper.selectMSalarydetailsByName(idAndYear)==null){
                MSalarydetails salarydetails = new MSalarydetails();
                //设置工号
                salarydetails.setsId(mBasestaff.getsId());
                //设置月份
                salarydetails.setsYearmonth(new SimpleDateFormat("yyyy-MM").format(date));
                //设置姓名
                salarydetails.setsName(mBasestaff.getsName());
                //设置基本工资
                salarydetails.setsBasesalary(mBasestaff.getsBasesalary());
                //绩效工资
                BigDecimal performanceSalary = getperformanceSalary(mBasestaff);
                salarydetails.setPerformance(performanceSalary);
                //员工提成
                BigDecimal commission = getcommissionSalary(mBasestaff);
                salarydetails.setCommission(commission);
                //设置缴纳保险
                BigDecimal insure= mBasestaff.getsBasesalary().multiply(new BigDecimal(0.105));
                salarydetails.setSocialSecurity(insure);
                //设置公积金
                BigDecimal fund= mBasestaff.getsBasesalary().multiply(new BigDecimal(0.05));
                salarydetails.setAccumulationFund(fund);
                //设置请假扣款
                BigDecimal leave= getleaveSalary(mBasestaff);
                salarydetails.setAskForLeave(leave);


                //应发工资
                BigDecimal salarypayable= mBasestaff.getsBasesalary().add(performanceSalary).add(commission).subtract(leave);
                salarydetails.setSalaryPayable(salarypayable);

                //个人所得税
                BigDecimal tax= gettaxSalary(salarypayable);
                salarydetails.setIncomeTax(tax);

                //实发工资
                BigDecimal actualSalary= salarypayable.subtract(insure).subtract(fund).subtract(tax);
                salarydetails.setNetSalary(actualSalary);

                //保存数据
                mSalarydetailsMapper.insertMSalarydetails(salarydetails);


            }
            //如果当月存在该用户的数据，则进行修改
            else {
                MSalarydetails salarydetails = mSalarydetailsMapper.selectMSalarydetailsByName(idAndYear);
                //设置基本工资
                salarydetails.setsBasesalary(mBasestaff.getsBasesalary());
                //绩效工资
                BigDecimal performanceSalary = getperformanceSalary(mBasestaff);
                salarydetails.setPerformance(performanceSalary);
                //员工提成
                BigDecimal commission = getcommissionSalary(mBasestaff);
                salarydetails.setCommission(commission);
                //设置缴纳保险
                BigDecimal insure= mBasestaff.getsBasesalary().multiply(new BigDecimal(0.105));
                salarydetails.setSocialSecurity(insure);
                //设置公积金
                BigDecimal fund= mBasestaff.getsBasesalary().multiply(new BigDecimal(0.05));
                salarydetails.setAccumulationFund(fund);
                //设置请假扣款
                BigDecimal leave= getleaveSalary(mBasestaff);
                salarydetails.setAskForLeave(leave);


                //应发工资
                BigDecimal salarypayable= mBasestaff.getsBasesalary().add(performanceSalary).add(commission).subtract(leave);
                salarydetails.setSalaryPayable(salarypayable);

                //个人所得税
                BigDecimal tax= gettaxSalary(salarypayable);
                salarydetails.setIncomeTax(tax);

                //实发工资
                BigDecimal actualSalary= salarypayable.subtract(insure).subtract(fund).subtract(tax);
                salarydetails.setNetSalary(actualSalary);

                //保存数据
                mSalarydetailsMapper.updateMSalarydetails(salarydetails);
            }
        }
        return null;
    }

    private BigDecimal gettaxSalary(BigDecimal salarypayable) {
        //查询税收规则
        IncomeTaxVo mTaxrulesList=mSalarydetailsMapper.selectMTaxList(salarypayable);
        if (mTaxrulesList!=null){
        //计算个人所得税
        BigDecimal tax=new BigDecimal(0);
        tax=tax.add(mTaxrulesList.getTax_base());
        tax=tax.add(salarypayable.subtract(mTaxrulesList.getMin_salary()).multiply(mTaxrulesList.getTax_rate()));
            return tax;
        }
        return null;
    }

    private BigDecimal getleaveSalary(MBasestaff mBasestaff) {
        //获取请假天数

        Integer leaveDays = mSalarydetailsMapper.selectLeaveDays(mBasestaff.getsId(), yearmonth);
        //计算请假扣款
        BigDecimal leave=new BigDecimal(0);
        if (leaveDays!=null){
            leave=mBasestaff.getsBasesalary().divide(new BigDecimal(22),2).multiply(new BigDecimal(leaveDays));
        }
        //查看是否有缺勤
        Calendar calendar = Calendar.getInstance();
        Integer day = calendar.get(Calendar.DAY_OF_MONTH); //获取当前天数
        //查看打卡天数，如果小于当前天数，则说明有缺勤
        Integer punchCard = mSalarydetailsMapper.selectPunchCard(mBasestaff.getsId(), yearmonth);
        if (punchCard<day){
            leave=leave.add(mBasestaff.getsBasesalary().divide(new BigDecimal(22),2).multiply(new BigDecimal(day-punchCard)));
        }

        return leave;
    }

    //获取提成的方法
    private BigDecimal getcommissionSalary(MBasestaff mBasestaff) {
        //获取签订的合同
        List<BigDecimal> performanceList=mSalarydetailsMapper.selectPerformancelist(mBasestaff.getsId(), yearmonth);
        BigDecimal sum=new BigDecimal(0);
        for (BigDecimal contractmoney : performanceList) {
            //如果签订的金额大于基本工资，则有提成
            if (contractmoney.subtract(mBasestaff.getsBasesalary()).compareTo(new BigDecimal(0))>0){
                BigDecimal num=contractmoney.subtract(mBasestaff.getsBasesalary()).multiply(new BigDecimal(0.08));
                sum=sum.add(num);
            }
        }
        return sum;
    }

    //获取绩效工资的方法
    private BigDecimal getperformanceSalary(MBasestaff mBasestaff){
        //获取当月业务量
        Integer businessVolume = mSalarydetailsMapper.selectbusinessVolume(mBasestaff.getsId(), yearmonth);
        //计算有绩效的
        if (businessVolume>0){
            //查找对应的奖励规则
            BigDecimal reward=mSalarydetailsMapper.selectperformanceReward(businessVolume);
            return mBasestaff.getsBasesalary().multiply(reward);
        }
        //计算没绩效的
        else {
            //查看是否有缺勤
            Calendar calendar = Calendar.getInstance();
            Integer day = calendar.get(Calendar.DAY_OF_MONTH); //获取当前天数
            //查看打卡天数，如果小于当前天数，则说明有缺勤
            Integer punchCard = mSalarydetailsMapper.selectPunchCard(mBasestaff.getsId(), yearmonth);
            //再查询请假天数，如果有请假，则缺勤
            Boolean leave = mSalarydetailsMapper.selectLeave(mBasestaff.getsId(), yearmonth);
            //查询对应条件
            BigDecimal reward = mSalarydetailsMapper.selectabsent((punchCard<day||leave)?1:0);
            return mBasestaff.getsBasesalary().multiply(reward);
        }
    }
}
